<!-- wyf 2022-3-30 -->
<template>
  <a-time-picker
    v-model:value="value1"
    :allow-clear="allowClear"
    :autofocus="autofocus"
    :bordered="bordered"
    :locale="locale.DatePicker"
    :clear-text="clearText"
    :disabled="disabled"
    :disabled-hours="disabledHoursFun"
    :disabled-minutes="disabledMinutesFun"
    :disabled-seconds="disabledSecondsFun"
    :format="format"
    :get-popup-container="getPopupContainer"
    :hide-disabled-options="hideDisabledOptions"
    :hour-step="hourStep"
    :input-read-only="inputReadOnly"
    :minute-step="minuteStep"
    :placeholder="placeholder"
    :popup-class-name="popupClassName"
    :popup-style="popupStyle"
    :second-step="secondStep"
    :show-now="showNow"
    :use12-hours="use12Hours"
    :value-format="valueFormat"
  >
    <template v-if="$slots.clearIcon" #clearIcon>
      <slot name="clearIcon" />
    </template>
    <template v-if="$slots.renderExtraFooter" #renderExtraFooter>
      <slot name="renderExtraFooter" />
    </template>
    <template v-if="$slots.suffixIcon" #suffixIcon>
      <slot name="suffixIcon" />
    </template>
    <slot />
  </a-time-picker>
</template>

<script>
import { TimePicker } from 'ant-design-vue'
import { defineComponent, computed } from 'vue'
import dayjs from 'dayjs'

export default defineComponent({
  name: 'ZTimePicker',
  components: {
    ATimePicker: TimePicker
  },
  props: {
    value: {
      type: [String, Object],
      default: ''
    },
    allowClear: Boolean,
    autofocus: {
      type: Boolean,
      default: false
    },
    bordered: {
      type: Boolean,
      default: true
    },
    clearText: {
      type: String,
      default: undefined
    },
    disabled: {
      type: Boolean,
      default: false
    },
    disabledHours: {
      type: Function,
      default: undefined
    },
    disabledMinutes: {
      type: Function,
      default: undefined
    },
    disabledSeconds: {
      type: Function,
      default: undefined
    },
    format: {
      type: String,
      default: 'HH:mm:ss'
    },
    getPopupContainer: {
      type: Function,
      default: undefined
    },
    hideDisabledOptions: {
      type: Boolean,
      default: false
    },
    hourStep: {
      type: Number,
      default: 1
    },
    inputReadOnly: {
      type: Boolean,
      default: false
    },
    minuteStep: {
      type: Number,
      default: 1
    },
    placeholder: {
      type: [String, Array],
      default: '请选择时间'
    },
    popupClassName: {
      type: String,
      default: undefined
    },
    popupStyle: {
      type: Object,
      default: undefined
    },
    secondStep: {
      type: Number,
      default: 1
    },
    showNow: {
      type: Boolean,
      default: undefined
    },
    use12Hours: {
      type: Boolean,
      default: false
    },
    valueFormat: {
      type: String,
      default: undefined
    },
    min: {
      type: String,
      default: undefined
    },
    max: {
      type: String,
      default: undefined
    }
  },
  setup(props, _ref) {
    const value1 = computed({
      get() {
        return props.value
      },
      set(val) {
        _ref.emit('update:value', val)
      }
    })

    const range = (start, end) => {
      const result = []

      for (let i = start; i < end; i++) {
        result.push(i)
      }

      return result
    }

    const getHours = (date) => {
      return dayjs(`${dayjs().format('YYYY-MM-DD')} ${date}`).hour()
    }
    const getMinute = (date) => {
      return dayjs(`${dayjs().format('YYYY-MM-DD')} ${date}`).minute()
    }
    const getSecond = (date) => {
      return dayjs(`${dayjs().format('YYYY-MM-DD')} ${date}`).second()
    }

    const minDate = computed(() => props.min)
    const maxDate = computed(() => props.max)

    const disabledHours = () => {
      let hours = []
      const maxMinute = maxDate.value ? getMinute(maxDate.value) : 59
      const maxSecond = maxDate.value ? getSecond(maxDate.value) : 59
      if (minDate.value) {
        hours = hours.concat(range(0, getHours(minDate.value)))
      }
      if (maxDate.value) {
        if (maxMinute === 0 && maxSecond === 0) {
          hours = hours.concat(range(getHours(maxDate.value), 24))
        } else {
          hours = hours.concat(range(getHours(maxDate.value) + 1, 24))
        }
      }
      return hours
    }

    const disabledMinutes = (selectedHour) => {
      const hours = getHours(selectedHour)
      const minHours = minDate.value ? getHours(minDate.value) : 0
      const maxHours = maxDate.value ? getHours(maxDate.value) : 24
      const minMinute = minDate.value ? getMinute(minDate.value) : 0
      const maxMinute = maxDate.value ? getMinute(maxDate.value) : 59
      const maxSecond = maxDate.value ? getSecond(maxDate.value) : 59
      if (hours < minHours) {
        return range(0, 60)
      } else if (hours > maxHours) {
        return range(0, 60)
      } else if (hours === minHours) {
        return range(0, minMinute)
      } else if (hours === maxHours) {
        if (maxSecond === 0) {
          return range(maxMinute, 60)
        } else {
          return range(maxMinute + 1, 60)
        }
      } else {
        return []
      }
    }

    const disabledSeconds = (selectedHour, selectedMinute) => {
      const hours = getHours(selectedHour)
      const minute = selectedMinute ? getMinute(`00:${selectedMinute.value}`) : 0
      const minHours = minDate.value ? getHours(minDate.value) : 0
      const maxHours = maxDate.value ? getHours(maxDate.value) : 24
      const minMinute = minDate.value ? getMinute(minDate.value) : 0
      const maxMinute = maxDate.value ? getMinute(maxDate.value) : 59
      const minSecond = minDate.value ? getSecond(minDate.value) : 0
      const maxSecond = maxDate.value ? getSecond(maxDate.value) : 59
      if (hours < minHours) {
        return range(0, 60)
      } else if (hours > maxHours) {
        return range(0, 60)
      } else if (hours === minHours) {
        if (minute < minMinute) {
          return range(0, 60)
        } else if (minute === minMinute) {
          return range(0, minSecond)
        } else {
          return []
        }
      } else if (hours === maxHours) {
        if (minute > maxMinute) {
          return range(0, 60)
        } else if (minute === maxMinute) {
          if (maxSecond !== 0) {
            return range(maxSecond, 60)
          }
          return range(maxSecond, 60)
        } else {
          return []
        }
      } else {
        return range(0, 60)
      }
    }

    const disabledHoursFun = computed(() => props.disabledHours ? props.disabledHours : minDate.value || maxDate.value ? disabledHours : undefined)
    const disabledMinutesFun = computed(() => props.disabledMinutes ? props.disabledMinutes : minDate.value || maxDate.value ? disabledMinutes : undefined)
    const disabledSecondsFun = computed(() => props.disabledSeconds ? props.disabledSeconds : minDate.value || maxDate.value ? disabledSeconds : undefined)

    return {
      value1,
      disabledHoursFun,
      disabledMinutesFun,
      disabledSecondsFun
    }
  }
})
</script>
